package org.hrds.rdupm.common.app.service.impl;

import java.util.ArrayList;
import java.util.List;

import org.hrds.rdupm.common.api.vo.ProductLibraryDTO;
import org.hrds.rdupm.common.app.service.ProductLibraryService;
import org.hrds.rdupm.harbor.app.service.HarborCustomRepoService;
import org.hrds.rdupm.harbor.app.service.HarborProjectService;
import org.hrds.rdupm.harbor.domain.entity.HarborCustomRepoDTO;
import org.hrds.rdupm.harbor.domain.entity.HarborRepository;
import org.hrds.rdupm.nexus.api.dto.NexusRepositoryDTO;
import org.hrds.rdupm.nexus.api.dto.NexusRepositoryQueryDTO;
import org.hrds.rdupm.nexus.app.service.NexusRepositoryService;
import org.hrds.rdupm.nexus.infra.constant.NexusConstants;
import org.hrds.rdupm.util.ExceptionConstants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import io.choerodon.core.exception.CommonException;

@Service
public class ProductLibraryServiceImpl implements ProductLibraryService {
    private static final Logger LOGGER = LoggerFactory.getLogger(ProductLibraryServiceImpl.class);

    @Autowired
    private NexusRepositoryService nexusRepositoryService;
    @Autowired
    private HarborProjectService harborProjectService;
    @Autowired
    private HarborCustomRepoService harborCustomRepoService;

    @Override
    public List<ProductLibraryDTO> listProduct(Long projectId, String repoType) {
        List<ProductLibraryDTO> productLibraryDTOList = new ArrayList<>();
        switch (repoType) {
            case NexusConstants.RepoType.MAVEN:
                // maven
                List<NexusRepositoryDTO> nexusRepositoryDTOList;
                try {
                    NexusRepositoryQueryDTO query = new NexusRepositoryQueryDTO();
                    query.setProjectId(projectId);
                    query.setRepoType(NexusConstants.RepoType.MAVEN);
                    nexusRepositoryDTOList = nexusRepositoryService.listRepoAll(query);
                } catch (Exception e) {
                    LOGGER.error("query maven error", e);
                    nexusRepositoryDTOList = new ArrayList<>();
                }
                nexusRepositoryDTOList.forEach(nexusRepositoryDTO -> {
                    productLibraryDTOList.add(new ProductLibraryDTO(nexusRepositoryDTO, NexusConstants.RepoType.MAVEN));
                });
                break;
            case NexusConstants.RepoType.HARBOR:
                // harbor
                List<HarborRepository> harborRepositoryList;
                try {
                    harborRepositoryList = harborProjectService.listByProject(projectId, new HarborRepository());
                } catch (Exception e) {
                    LOGGER.error("query harbor error", e);
                    harborRepositoryList = new ArrayList<>();
                }

                //harbor-customize
                List<HarborCustomRepoDTO> harborCustomRepoDTOList;
                try {
                    harborCustomRepoDTOList = harborCustomRepoService.listByProjectId(projectId);
                } catch (Exception e) {
                    LOGGER.error("query harbor custom repo error", e);
                    harborCustomRepoDTOList = new ArrayList<>();
                }

                harborRepositoryList.forEach(harborRepository -> {
                    productLibraryDTOList.add(new ProductLibraryDTO(harborRepository));
                });
                harborCustomRepoDTOList.forEach(harborCustomRepoDTO -> {
                    productLibraryDTOList.add(new ProductLibraryDTO(harborCustomRepoDTO));
                });
                break;
            case NexusConstants.RepoType.NPM:
                // NPM
                List<NexusRepositoryDTO> nexusRepositoryNpmDTOList;
                try {
                    NexusRepositoryQueryDTO query = new NexusRepositoryQueryDTO();
                    query.setProjectId(projectId);
                    query.setRepoType(NexusConstants.RepoType.NPM);
                    nexusRepositoryNpmDTOList = nexusRepositoryService.listRepoAll(query);
                } catch (Exception e) {
                    LOGGER.error("query npm error", e);
                    nexusRepositoryNpmDTOList = new ArrayList<>();
                }
                nexusRepositoryNpmDTOList.forEach(nexusRepositoryDTO -> {
                    productLibraryDTOList.add(new ProductLibraryDTO(nexusRepositoryDTO, NexusConstants.RepoType.NPM));
                });
                break;
            default:
                throw new CommonException(ExceptionConstants.HarborProjectCode.RDUPM_UNSUPPORTED_REPO_TYPE);
        }
        return productLibraryDTOList;
    }

    @Override
    public List<ProductLibraryDTO> listByProject(Long projectId) {
        // harbor
        List<HarborRepository> harborRepositoryList = null;
        try {
            harborRepositoryList = harborProjectService.listByProject(projectId, new HarborRepository());
        } catch (Exception e) {
            LOGGER.error("query harbor error", e);
            harborRepositoryList = new ArrayList<>();
        }

        //harbor-customize
        List<HarborCustomRepoDTO> harborCustomRepoDTOList = null;
        try {
            harborCustomRepoDTOList = harborCustomRepoService.listByProjectId(projectId);
        } catch (Exception e) {
            LOGGER.error("query harbor custom repo error", e);
            harborCustomRepoDTOList = new ArrayList<>();
        }

        // maven
        List<NexusRepositoryDTO> nexusRepositoryDTOList = null;
        try {
            NexusRepositoryQueryDTO query = new NexusRepositoryQueryDTO();
            query.setProjectId(projectId);
            query.setRepoType(NexusConstants.RepoType.MAVEN);
            nexusRepositoryDTOList = nexusRepositoryService.listRepoAll(query);
        } catch (Exception e) {
            LOGGER.error("query maven error", e);
            nexusRepositoryDTOList = new ArrayList<>();
        }

        // NPM
        List<NexusRepositoryDTO> nexusRepositoryNpmDTOList = null;
        try {
            NexusRepositoryQueryDTO query = new NexusRepositoryQueryDTO();
            query.setProjectId(projectId);
            query.setRepoType(NexusConstants.RepoType.NPM);
            nexusRepositoryNpmDTOList = nexusRepositoryService.listRepoAll(query);
        } catch (Exception e) {
            LOGGER.error("query npm error", e);
            nexusRepositoryNpmDTOList = new ArrayList<>();
        }

        // 返回
        List<ProductLibraryDTO> productLibraryDTOList = new ArrayList<>();
        harborRepositoryList.forEach(harborRepository -> {
            productLibraryDTOList.add(new ProductLibraryDTO(harborRepository));
        });
        harborCustomRepoDTOList.forEach(harborCustomRepoDTO -> {
            productLibraryDTOList.add(new ProductLibraryDTO(harborCustomRepoDTO));
        });
        nexusRepositoryDTOList.forEach(nexusRepositoryDTO -> {
            productLibraryDTOList.add(new ProductLibraryDTO(nexusRepositoryDTO, NexusConstants.RepoType.MAVEN));
        });
        nexusRepositoryNpmDTOList.forEach(nexusRepositoryDTO -> {
            productLibraryDTOList.add(new ProductLibraryDTO(nexusRepositoryDTO, NexusConstants.RepoType.NPM));
        });
        return productLibraryDTOList;
    }
}
